home *** CD-ROM | disk | FTP | other *** search
- Unit PrnInout;
-
- interface
-
- uses Dos,
- Time,
- StrTool,
- SerInOut,
- KeyScrn;
-
- Const Devicename : Str15 = 'Drucker';
- IgnorePaperOut: Boolean = false;
- TimeOut : Byte = 100;{50 sec bei XT }
- TO_Versuche : Word = 1; { Time-Out-Versuche }
-
- Var NoError :Boolean;
-
- procedure AssignAux(var F: Text; Port,BaudRate,StopBits,DataBits:byte;
- Parity :Paritytype);{96 =9600 Baud}
-
- procedure AssignLST(Var F: Text; Port :Byte);
-
- Procedure SetDeviceBinary(Var F:Text);
-
-
- implementation
- {$S-,R-}
-
- type
- TextBuf = array[0..127] of Char;
- TextRec = record
- Handle: Word;
- Mode: Word;
- BufSize: Word;
- Private: Word;
- BufPos: Word;
- BufEnd: Word;
- BufPtr: ^TextBuf;
- OpenProc: Pointer;
- InOutProc: Pointer;
- FlushProc: Pointer;
- CloseProc: Pointer;
- PrnPort,PrnParam: Word; { zwei neue Felder }
- UserFill: array[1..12] of Byte; { um 4 Bytes kleiner }
- Name: array[0..79] of Char;
- Buffer: TextBuf;
- end;
-
- const
- fmClosed = $D7B0;
- fmInput = $D7B1;
- fmOutput = $D7B2;
- fmInOut = $D7B3;
-
- LPTermask :Byte=$39;
-
-
- VAR Ok :BOOLEAN;
- Print_Error :Boolean;
- OldLPTtimeout :Byte;
-
-
- Procedure SetTimeOut(Time,Port:Byte;Serial:Boolean);
- Var T :LongInt;
- begin
- If Serial then
- SerTimeout:=Time
- else
- begin
- oldLPTtimeout:=Mem[64:120+Port];
- Mem[64:120+Port]:=Time;
- end;
- end;
-
- Procedure RestoreTimeOut(Port:Byte;Serial:Boolean);
- begin
- If Not Serial then
- Mem[64:120+Port]:=OldLPTtimeout;
- end;
-
- FUNCTION OutError(Status:BYTE;Serial:Boolean):BOOLEAN;
- Const Trie_Count:Word =0;
- VAR StatusZeile : STR80;
- Ch : CHAR;
- BEGIN
- OutError := FALSE;
- StatusZeile :=Devicename+': Unbekannter Fehler';
- Inc(Trie_Count);
- If Serial Then
- begin
- IF (Status and $80)<>0 THEN
- begin
- If Trie_Count<=TO_Versuche then Exit;
- StatusZeile := 'Time Out Fehler des '+Devicename;
- end;
- end
- else
- begin
- IF ((Status and $20)<>0) and Not(ignorepaperout) THEN
- StatusZeile := Devicename+' hat kein Papier'
- ELSE IF (Status and $10)=0 THEN
- StatusZeile := Devicename+' nicht Online'
- ELSE IF (Status and $40)=0 THEN
- StatusZeile := 'Keine Reaktion des '+Devicename+'s'
- ELSE IF (Status and $80)=0 THEN
- StatusZeile := Devicename+ ' beschäftigt'
- ELSE IF (Status and $08)<>0 THEN
- StatusZeile := ' I/O Fehler des '+Devicename+'s'
- ELSE IF (Status and $01)<>0 THEN
- begin
- If Trie_Count<=TO_Versuche then Exit;
- StatusZeile := ' Time Out Fehler des '+Devicename+'s';
- end;
- end;
- Trie_Count:=0;
- CH:=SelectError(Statuszeile+' -> Abbrechen - Wiederholen ?'
- ,'Fehler:',['A','W']);
- IF Ch='A' THEN begin NoError:=false;OutError:=True end;
- END;
-
- procedure AuxoutChar(C: Char);
- Var Error:Byte;
- begin
- Ok:= Not(NoError);
- WHILE NOT Ok DO
- BEGIN
- OutSerPort(Ord(C),Error);
- If Error <>0
- THEN Ok := OutError(Error,true)
- ELSE Ok := TRUE;
- END;
- end;
-
-
- {$F+}
-
- function AuxOutput(var F: TextRec): Integer;
- var
- P : Integer;
- begin
- with F do
- begin
- If BufPos>0 then
- begin
- BufPos := 0;
- AuxOutChar(BufPtr^[0]);
- end;
- end;
- AuxOutput := 0;
- end;
-
- function AuxIgnore(var F : TextRec) : Integer;
- begin
- AuxIgnore := 0;
- end;
-
- function AuxClose(var F : TextRec) : Integer;
- begin
- RestoretimeOut(F.PrnPort,true);
- AuxClose := 0;
- end;
-
- function AuxOpen(var F : TextRec) : Integer;
- begin
- with F do
- begin
- Noerror:=true;
- if Mode = fmInput then
- begin
- InOutProc := @AuxIgnore;
- FlushProc := @AuxIgnore;
- end else
- begin
- Mode := fmOutput;
- InOutProc:= @AuxOutput;
- FlushProc:= @AuxOutput;
- end;
- CloseProc := @AuxClose;
- end;
- AuxOpen := 0;
- end;
-
- {$F-}
-
- procedure AssignAux;
- var Param :Word;
- begin
- Port:=Pred(Port) and 3;
- SetSeriell(Port+1,Baudrate,Stopbits,Databits,Parity);
- SetTimeOut(Timeout,Port,true);
- with TextRec(F) do
- begin
- Handle := $FFFF;
- Mode := fmClosed;
- BufSize := 1;
- BufPtr := @Buffer;
- OpenProc := @AuxOpen;
- PrnPort := Port;
- PrnParam := Param;
- Name[0] := #0;
- end;
- end;
-
-
- PROCEDURE Print_INT17(Port :Word;C:CHAR); far; assembler; { Neuer Druckertreiber }
- ASM { Print }
- MOV AL,NoError
- MOV Print_Error,AL
- @@Test:OR AL,AL
- JE @@fertig
- XOR AX,AX
- MOV Print_Error,AL
- MOV AL,C
- MOV DX,Port
- INT 17H
- MOV AL,AH
- XOR AH,10H
- AND AH,LPTermask
- JE @@fertig
- XOR AH,AH
- PUSH AX
- XOR AX,AX
- PUSH AX
- CALL OutError
- XOR AL,1
- MOV Print_Error,AL
- jmp @@test
- @@fertig:
- END; { Print }
-
- (* bringt keine Speedvorteile !!!!
- PROCEDURE Print_HW(Port :Word;C:CHAR);far; assembler;
- { Hier ist Port die Hardware-Portadresse und nicht die logische Adresse }
- ASM { Print_HW }
- MOV AL,NoError
- MOV Print_Error,AL
- @@Test:OR AL,AL
- JE @@fertig
- MOV Print_Error,0
- MOV AL,C { Zeichen in AL }
- MOV DX,Port { Port-Adresse ins DX-Register}
- OUT DX,AL
- MOV BX,TimeOutCnt
- MOV Systimer,BX { Systimer auf Timeout setzen }
- INC DX
- @@Wait:IN AL, DX
- and Al,Al
- js @@is_ok { Sign-Bit :Ok !! }
- CMP SysTimer,0 { Systimer wird alle 1/18 sec dekrementiert}
- JG @@Wait { >0 : Systimer noch nicht abgelaufen }
- @@TimeOut:
- OR AL,1
- AND AL,0F9H
- jmp @@stat
- @@is_Ok:
- INC DX
- MOV AL,0DH
- CLI
- OUT DX,AL
- nop
- nop
- jmp @@A
- @@A: jmp @@B
- @@B: MOV AL,0CH
- OUT DX,AL { Strobe-Impuls }
- STI
- nop
- nop
- nop
- DEC DX
- IN AL,DX
- AND AL,0F8H
- @@stat:XOR AL,48H
- MOV AH,AL { AH enthält Status ungefiltert }
- XOR AL,10H { Invertiere OnLine-Bit }
- AND AL,LPTERMask { AL=0 :Status=ok}
- @@printed:
- JE @@fertig
- MOV AL,AH
- XOR AH,AH { AX= Status }
- PUSH AX
- XOR AX,AX
- PUSH AX
- CALL OutError
- XOR AL,1
- MOV Print_Error,AL
- jmp @@test
- @@fertig:
- END; { Print }
- *)
-
- {$F+}
-
- function LSTOutput(var F: TextRec):Integer; assembler;
- asm
- LES DI,F
- CMP TextRec(ES:[DI]).Bufpos,0
- JE @@Done
- MOV TextRec(ES:[DI]).Bufpos,0
- PUSH TextRec(ES:[DI]).PrnPort
- LES DI,TextRec(ES:[DI]).BufPtr
- PUSH WORD PTR ES:[DI]
- CALL Print_INT17
- @@Done:
- XOR AX,AX
- end;
- (*
- ** Pascal :
- function LSTOutput(var F: TextRec): Integer;
- begin
- with F do
- begin
- If BufPos>0 then
- PrintFunc(PrnPort,BufPtr^[0]);
- BufPos := 0;
- end;
- LSTOutput := 0;
- end;
- *)
-
-
- function LSTIgnore(var F : TextRec) : Integer;
- begin
- LSTIgnore := 0;
- end;
-
- function LSTClose(var F : TextRec) : Integer;
- begin
- RestoretimeOut(F.PrnPort,false);
- LSTClose := 0;
- end;
-
- function LSTOpen(var F : TextRec) : Integer;
- begin
- If IgnorePaperout then
- LPTermask:= $19 else LPTermask:=$39;
- Noerror:=true;
- with F do
- begin
- SetTimeOut(Timeout,PrnPort,false);
- if Mode = fmInput then
- begin
- InOutProc := @LSTIgnore;
- FlushProc := @LSTIgnore;
- end else
- begin
- Mode := fmOutput;
- InOutProc:= @LSTOutput;
- FlushProc:= @LSTOutput;
- end;
- CloseProc := @LSTClose;
- end;
- LSTOpen := 0;
- end;
-
- {$F-}
-
- procedure AssignLST;
- Var Direct:Boolean;
-
- begin
- Port:=Pred(Port);
- IF Port>3 Then Port:=0;
- with TextRec(F) do
- begin
- Handle := $FFFF;
- Mode := fmClosed;
- BufSize := 1;
- BufPtr := @Buffer;
- OpenProc := @LSTOpen;
- PrnPort:= Port;
- PrnParam := 0;
- Name[0] := #0;
- end;
- end;
-
- {$F+}
- Procedure SetDeviceBinary(Var F:Text);
- Var R:Registers;
- begin
-
- With TextRec(F) do
- begin
- If Handle=$FFFF then Exit;
- R.AX:=$4400;
- R.BX:=Handle;
- MsDos(R);
- If ((R.Flags and Fcarry)=0) and ((R.DX and $80)<>0) then
- begin
- R.DH:=0;
- R.DL:=(R.DL and $EF) or $20;
- R.AX:=$4401;
- R.BX:=Handle;
- MSDOS(R);
- end;
- end;
- end;
-
- end.